"""
任务处理工具
提供后台任务和异步处理功能
"""
import os
import time
import logging
import threading
from functools import wraps
from flask import current_app

# 配置后台任务日志
logger = logging.getLogger('background_tasks')
logger.setLevel(logging.INFO)


def run_in_background(func):
    """
    将函数在后台线程中运行的装饰器
    
    参数:
        func: 要在后台运行的函数
    
    返回:
        包装后的函数
    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        thread = threading.Thread(target=func, args=args, kwargs=kwargs)
        thread.daemon = True  # 设置为守护线程，随主线程退出而退出
        thread.start()
        return thread
    return wrapper


@run_in_background
def async_task(func, *args, **kwargs):
    """
    异步执行任务
    
    参数:
        func: 要执行的函数
        *args, **kwargs: 传递给函数的参数
    """
    try:
        start_time = time.time()
        logger.info(f"开始执行异步任务: {func.__name__}")
        result = func(*args, **kwargs)
        elapsed = time.time() - start_time
        logger.info(f"异步任务 {func.__name__} 已完成，耗时: {elapsed:.2f}秒")
        return result
    except Exception as e:
        logger.error(f"异步任务 {func.__name__} 执行失败: {str(e)}")


def with_retries(max_retries=3, delay=1):
    """
    带重试机制的函数装饰器
    
    参数:
        max_retries: 最大重试次数
        delay: 重试间隔（秒）
    
    返回:
        装饰器函数
    """
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            retries = 0
            while retries < max_retries:
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    retries += 1
                    if retries >= max_retries:
                        logger.error(f"函数 {func.__name__} 达到最大重试次数 ({max_retries})，失败: {str(e)}")
                        raise
                    logger.warning(f"函数 {func.__name__} 调用失败 (重试 {retries}/{max_retries}): {str(e)}")
                    time.sleep(delay * retries)  # 指数退避
        return wrapper
    return decorator


class BatchProcessor:
    """批处理处理器，用于高效处理大量数据"""
    
    def __init__(self, batch_size=100, callback=None):
        """
        初始化批处理处理器
        
        参数:
            batch_size: 每批处理的数据量
            callback: 处理完一批数据后的回调函数
        """
        self.batch_size = batch_size
        self.callback = callback
        self.items = []
    
    def add(self, item):
        """
        添加项目到批处理
        
        参数:
            item: 要添加的项目
        """
        self.items.append(item)
        
        # 如果达到批处理大小，处理当前批次
        if len(self.items) >= self.batch_size:
            self.process()
    
    def process(self):
        """处理当前批次中的所有项目"""
        if not self.items:
            return
        
        try:
            # 如果提供了回调函数，调用它处理批次
            if self.callback:
                self.callback(self.items)
            logger.info(f"已处理一批 {len(self.items)} 项")
        except Exception as e:
            logger.error(f"批处理失败: {str(e)}")
        
        # 清空已处理的项目
        self.items = []
    
    def __enter__(self):
        """支持上下文管理器"""
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """退出上下文时处理剩余项目"""
        self.process() 